package com.cencat.vehicle.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.common.util.RedisUtil;
import com.cencat.vehicle.dto.*;
import com.cencat.vehicle.entity.Vehicle;
import com.cencat.vehicle.mapper.VehicleMapper;
import com.cencat.vehicle.service.VehicleService;
import com.cencat.vehicle.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 车辆服务实现类
 *
 * @author cencat
 * @version 1.0
 * @since 2024-12-19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VehicleServiceImpl implements VehicleService {

    private final VehicleMapper vehicleMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    private static final String VEHICLE_CACHE_KEY = "vehicle:";
    private static final String VEHICLE_LOCATION_KEY = "vehicle:location:";
    private static final String VEHICLE_STATISTICS_KEY = "vehicle:statistics";
    private static final long CACHE_EXPIRE_TIME = 3600; // 1小时

    @Override
    public Page<VehicleVO> getVehiclePage(Page<VehicleVO> page, VehicleQueryDTO query) {
        log.info("分页查询车辆列表，页码：{}，大小：{}，查询条件：{}", page.getCurrent(), page.getSize(), query);
        return vehicleMapper.selectVehiclePage(page, query);
    }

    @Override
    public VehicleVO getVehicleById(Long vehicleId) {
        log.info("根据ID获取车辆详情，车辆ID：{}", vehicleId);
        
        // 先从缓存获取
        String cacheKey = VEHICLE_CACHE_KEY + vehicleId;
        VehicleVO cachedVehicle = (VehicleVO) redisTemplate.opsForValue().get(cacheKey);
        if (cachedVehicle != null) {
            return cachedVehicle;
        }
        
        VehicleVO vehicle = vehicleMapper.selectVehicleById(vehicleId);
        if (vehicle != null) {
            // 缓存结果
            redisTemplate.opsForValue().set(cacheKey, vehicle, CACHE_EXPIRE_TIME, java.util.concurrent.TimeUnit.SECONDS);
        }
        return vehicle;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createVehicle(VehicleCreateDTO createDTO) {
        log.info("创建车辆，参数：{}", createDTO);
        
        // 检查车牌号是否已存在
        if (checkVehicleExists(createDTO.getPlateNumber())) {
            throw new RuntimeException("车牌号已存在：" + createDTO.getPlateNumber());
        }
        
        Vehicle vehicle = new Vehicle();
        // 设置车辆属性
        vehicle.setPlateNumber(createDTO.getPlateNumber());
        vehicle.setVehicleType(createDTO.getVehicleType());
        vehicle.setBrand(createDTO.getBrand());
        vehicle.setModel(createDTO.getModel());
        vehicle.setColor(createDTO.getColor());
        vehicle.setLoadCapacity(createDTO.getLoadCapacity());
        vehicle.setDriverId(createDTO.getDriverId());
        vehicle.setMerchantId(createDTO.getMerchantId());
        vehicle.setStatus(1); // 默认可用状态
        vehicle.setCreateTime(LocalDateTime.now());
        vehicle.setUpdateTime(LocalDateTime.now());
        
        int result = vehicleMapper.insertVehicle(vehicle);
        
        if (result > 0) {
            // 清除相关缓存
            clearVehicleCache();
        }
        
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateVehicle(VehicleUpdateDTO updateDTO) {
        log.info("更新车辆，参数：{}", updateDTO);
        
        Vehicle vehicle = new Vehicle();
        vehicle.setId(updateDTO.getId());
        vehicle.setPlateNumber(updateDTO.getPlateNumber());
        vehicle.setVehicleType(updateDTO.getVehicleType());
        vehicle.setBrand(updateDTO.getBrand());
        vehicle.setModel(updateDTO.getModel());
        vehicle.setColor(updateDTO.getColor());
        vehicle.setLoadCapacity(updateDTO.getLoadCapacity());
        vehicle.setDriverId(updateDTO.getDriverId());
        vehicle.setMerchantId(updateDTO.getMerchantId());
        vehicle.setUpdateTime(LocalDateTime.now());
        
        int result = vehicleMapper.updateVehicle(vehicle);
        
        if (result > 0) {
            // 清除缓存
            String cacheKey = VEHICLE_CACHE_KEY + updateDTO.getId();
            redisTemplate.delete(cacheKey);
            clearVehicleCache();
        }
        
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteVehicle(Long vehicleId) {
        log.info("删除车辆，车辆ID：{}", vehicleId);
        
        int result = vehicleMapper.deleteVehicle(vehicleId);
        
        if (result > 0) {
            // 清除缓存
            String cacheKey = VEHICLE_CACHE_KEY + vehicleId;
            redisTemplate.delete(cacheKey);
            clearVehicleCache();
        }
        
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDeleteVehicles(List<Long> vehicleIds) {
        log.info("批量删除车辆，车辆ID列表：{}", vehicleIds);
        
        int result = vehicleMapper.batchDeleteVehicles(vehicleIds);
        
        if (result > 0) {
            // 清除缓存
            vehicleIds.forEach(id -> {
                String cacheKey = VEHICLE_CACHE_KEY + id;
                redisTemplate.delete(cacheKey);
            });
            clearVehicleCache();
        }
        
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateVehicleStatus(Long vehicleId, Integer status) {
        log.info("更新车辆状态，车辆ID：{}，状态：{}", vehicleId, status);
        
        int result = vehicleMapper.updateVehicleStatus(vehicleId, status);
        
        if (result > 0) {
            // 清除缓存
            String cacheKey = VEHICLE_CACHE_KEY + vehicleId;
            redisTemplate.delete(cacheKey);
        }
        
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateVehicleStatus(List<Long> vehicleIds, Integer status) {
        log.info("批量更新车辆状态，车辆ID列表：{}，状态：{}", vehicleIds, status);
        
        int result = vehicleMapper.batchUpdateVehicleStatus(vehicleIds, status);
        
        if (result > 0) {
            // 清除缓存
            vehicleIds.forEach(id -> {
                String cacheKey = VEHICLE_CACHE_KEY + id;
                redisTemplate.delete(cacheKey);
            });
        }
        
        return result > 0;
    }

    @Override
    public VehicleStatisticsVO getVehicleStatistics(LocalDateTime startTime, LocalDateTime endTime) {
        log.info("获取车辆统计数据，开始时间：{}，结束时间：{}", startTime, endTime);
        return vehicleMapper.selectVehicleStatistics(startTime, endTime);
    }

    @Override
    public List<VehicleTrendVO> getVehicleTrend(Integer days) {
        log.info("获取车辆趋势数据，天数：{}", days);
        return vehicleMapper.selectVehicleTrend(days);
    }

    @Override
    public List<VehicleRankingVO> getVehicleRanking(Integer type, Integer limit) {
        log.info("获取车辆排行榜，类型：{}，限制数量：{}", type, limit);
        return vehicleMapper.selectVehicleRanking(type, limit);
    }

    @Override
    public List<VehicleDistributionVO> getVehicleDistribution(Integer type) {
        log.info("获取车辆分布数据，类型：{}", type);
        return vehicleMapper.selectVehicleDistribution(type);
    }

    @Override
    public List<VehicleVO> getDriverVehicles(Long driverId, Integer status) {
        log.info("获取司机车辆列表，司机ID：{}，状态：{}", driverId, status);
        return vehicleMapper.selectDriverVehicles(driverId, status);
    }

    @Override
    public List<VehicleVO> getMerchantVehicles(Long merchantId, Integer status) {
        log.info("获取商户车辆列表，商户ID：{}，状态：{}", merchantId, status);
        return vehicleMapper.selectMerchantVehicles(merchantId, status);
    }

    @Override
    public List<VehicleVO> getNearbyVehicles(Double longitude, Double latitude, Double radius, Integer limit) {
        log.info("获取附近车辆，经度：{}，纬度：{}，半径：{}，限制数量：{}", longitude, latitude, radius, limit);
        return vehicleMapper.selectNearbyVehicles(longitude, latitude, radius, limit);
    }

    @Override
    public List<VehicleMatchVO> smartVehicleMatch(VehicleMatchDTO matchDTO) {
        log.info("智能车辆匹配，参数：{}", matchDTO);
        return vehicleMapper.selectSmartVehicleMatch(matchDTO);
    }

    @Override
    public List<VehicleTrackVO> getVehicleTrack(Long vehicleId, LocalDateTime startTime, LocalDateTime endTime) {
        log.info("获取车辆轨迹，车辆ID：{}，开始时间：{}，结束时间：{}", vehicleId, startTime, endTime);
        return vehicleMapper.selectVehicleTrack(vehicleId, startTime, endTime);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateVehicleLocation(VehicleLocationDTO locationDTO) {
        log.info("更新车辆位置，参数：{}", locationDTO);
        
        // 更新数据库
        int result = vehicleMapper.updateVehicleLocation(locationDTO);
        
        if (result > 0) {
            // 更新Redis缓存
            String locationKey = VEHICLE_LOCATION_KEY + locationDTO.getVehicleId();
            redisTemplate.opsForValue().set(locationKey, locationDTO, CACHE_EXPIRE_TIME, java.util.concurrent.TimeUnit.SECONDS);
        }
        
        return result > 0;
    }

    @Override
    public List<VehicleMaintenanceVO> getVehicleMaintenance(Long vehicleId) {
        log.info("获取车辆维护记录，车辆ID：{}", vehicleId);
        return vehicleMapper.selectVehicleMaintenance(vehicleId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addVehicleMaintenance(VehicleMaintenanceDTO maintenanceDTO) {
        log.info("添加车辆维护记录，参数：{}", maintenanceDTO);
        return vehicleMapper.insertVehicleMaintenance(maintenanceDTO) > 0;
    }

    @Override
    public VehicleInsuranceVO getVehicleInsurance(Long vehicleId) {
        log.info("获取车辆保险信息，车辆ID：{}", vehicleId);
        return vehicleMapper.selectVehicleInsurance(vehicleId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateVehicleInsurance(VehicleInsuranceDTO insuranceDTO) {
        log.info("更新车辆保险信息，参数：{}", insuranceDTO);
        return vehicleMapper.updateVehicleInsurance(insuranceDTO) > 0;
    }

    @Override
    public VehicleExportVO exportVehicles(VehicleQueryDTO query) {
        log.info("导出车辆数据，查询条件：{}", query);
        return vehicleMapper.selectVehicleExport(query);
    }

    @Override
    public VehicleDetailVO getVehicleDetail(Long vehicleId) {
        log.info("获取车辆详细信息，车辆ID：{}", vehicleId);
        return vehicleMapper.selectVehicleDetail(vehicleId);
    }

    @Override
    public List<VehicleVO> searchVehicles(String keyword, String searchType, Integer limit) {
        log.info("搜索车辆，关键词：{}，搜索类型：{}，限制数量：{}", keyword, searchType, limit);
        return vehicleMapper.searchVehicles(keyword, searchType, limit);
    }

    @Override
    public List<VehicleVO> getRecommendedVehicles(Long driverId, Integer limit) {
        log.info("获取推荐车辆，司机ID：{}，限制数量：{}", driverId, limit);
        return vehicleMapper.selectRecommendedVehicles(driverId, limit);
    }

    @Override
    public VehiclePerformanceVO getVehiclePerformance(Long vehicleId) {
        log.info("获取车辆性能数据，车辆ID：{}", vehicleId);
        return vehicleMapper.selectVehiclePerformance(vehicleId);
    }

    @Override
    public List<String> getVehicleOptimizationSuggestions(Long vehicleId) {
        log.info("获取车辆优化建议，车辆ID：{}", vehicleId);
        return vehicleMapper.selectVehicleOptimizationSuggestions(vehicleId);
    }

    @Override
    public Boolean checkVehicleExists(String plateNumber) {
        log.info("检查车辆是否存在，车牌号：{}", plateNumber);
        return vehicleMapper.checkVehicleExists(plateNumber) > 0;
    }

    @Override
    public List<VehicleVO> getSimilarVehicles(Long vehicleId, Integer limit) {
        log.info("获取相似车辆，车辆ID：{}，限制数量：{}", vehicleId, limit);
        return vehicleMapper.selectSimilarVehicles(vehicleId, limit);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateVehicleRating(Long vehicleId, Double rating) {
        log.info("更新车辆评分，车辆ID：{}，评分：{}", vehicleId, rating);
        
        int result = vehicleMapper.updateVehicleRating(vehicleId, rating);
        
        if (result > 0) {
            // 清除缓存
            String cacheKey = VEHICLE_CACHE_KEY + vehicleId;
            redisTemplate.delete(cacheKey);
        }
        
        return result > 0;
    }

    /**
     * 清除车辆相关缓存
     */
    private void clearVehicleCache() {
        redisTemplate.delete(VEHICLE_STATISTICS_KEY);
    }

}